<template>
  <div class="msg-content chatx">
  <div class="chat">
    <!-- 好友列表 -->
    <div class="list">
      <span class="title">最近联系</span>
      <div class="user-list">
        <!-- 没有联系人的提示内容 -->
        <NoContent :show="friends.length === 0" text="暂无联系人"/>
        <!-- 联系人列表 -->
        <template v-for="f in friends">
          <a class="data" @click="handleChat(f)" :class="{active: to === f.id}" v-active>
            <img :src="$api.preview(f.avatar)"/>
            <em>{{ f.nickName ?? f.tel }}</em>
            <b class="dot" v-show="f.unreadCount > 0">{{ f.unreadCount }}</b>
          </a>
        </template>
      </div>
    </div>
    <!-- 聊天窗口 -->
    <div class="content">
      <!-- 没有选择联系人的情况下，默认显示的效果 -->
      <NoContent :show="to == null" text="选择联系人" :img="false" style="margin: 0 auto"/>

      <div class="header clearfix" v-if="to != null">
        <span>与<b>{{ friend.nickName ?? friend.tel }}</b>的对话</span>
        <a class="btn" @click.prevent="handleAddBlack(friend.id)">加入黑名单</a>
      </div>
      <!-- 显示聊天内容 -->
      <div class="msg" style="height: auto">
        <!-- 聊天内容， 没有聊天内容的时候，提示  开始聊天 -->
        <NoContent :show="to != null && messages.length == 0" :img="false" text="无聊天内容，开始聊天"/>
        <a class="no-data" v-if="to!=null && !finished" @click="queryChatRecords">查看历史聊天信息</a>
        <div class="clearfix" v-for="(msg,index) in messages" :key="msg.id">
          <div :class="{t: msg.toUser === to , f: msg.toUser !== to }">
            <div class="info">
              <img :src="$api.preview(msg.avatar)"/>
              <time>{{ msg.createTime }}</time>
            </div>
            <div class="text">{{ msg.content }}</div>
          </div>
        </div>
        <a class="message" v-if="forbidden">您已被对方加入了黑名单、无法发送聊天消息给对方</a>
      </div>
      <!-- 显示 发送按钮 -->
      <footer v-if="to !=null">
        <textarea placeholder="请输入聊天信息" v-model.trim="content" @keydown.enter.prevent="sendMessage"></textarea>
        <a class="btn" href="javascript:void(0)" @click="sendMessage">发送消息</a>
      </footer>
    </div>

  </div>
  </div>
</template>

<script>
import NoContent from "../NoContent.vue";
import {mapGetters} from 'vuex' ;

export default {
  components: {
    NoContent,
  },
  computed: {
    friend: {
      get() {
        return this.to == null ? {} : this.friends.find(f => f.id === this.to) ?? {};
      },
      set(val) {
        this.to = (val != null ? val.id : val);
      }
    },
    offset() { // 聊天偏移量
      return this.messages.length;
    },
    ...mapGetters(["currentUser"])
  },
  data() {
    return {
      to: this.$route.query.to,
      nick: null,
      friends: [],  // 好友列表
      messages: [], // 聊天消息
      socket: false, // 存储 websocket对象
      content: "", // 聊天内容
      finished: false, // 是否显示完聊天信息
      forbidden: false, // 禁止发送聊天信息
    }
  },
  created() {
    this.queryFriendList();
  },
  mounted() {
    this.createWebSocket();
    // 聊天窗口的滚动条出现到底部
    if (this.to!=null) this.scrollToBottom();
  },
  methods: {
    createWebSocket() {
      this.socket = new WebSocket(this.$api.chatWebSocketUrl(this.$store.getters.currentUser.id));
      this.socket.onerror = () => {
      }
      this.socket.onclose = () => { // 链接断开后，
        console.log("链接断开、重新链接");
        this.createWebSocket();
      }
      //监听 服务器发送的消息
      this.socket.onmessage = (evt) => {
        if (evt.data === "403") { // 说明您已被对方加入了黑名单，无法正常发送消息
            this.forbidden = true ;
            this.$nextTick(() => {
              this.scrollToBottom();
            });
            return ;
        }
        this.forbidden = false ;
        let message = JSON.parse(evt.data);
        // 如果聊天信息是 自己发送的，或者 聊天信息是 正在聊天的好友发送的
        if (message.fromUser === this.currentUser.id || message.fromUser === this.to) {
          // 有信息来、就把分页的页面重置为 1
          this.messages.push(message);
          // 拖动滚动条到底部
          this.$nextTick(() => {
            this.scrollToBottom();
          });
          // 如果当前消息 是 对方发的，需要将该消息标记为已读, 且正在聊天，将该消息标记为已读。
          if (message.fromUser == this.to) {
            // 更新消息的状态
            this.$api.updateMessageState(message.id).then(ret=> {
               if (ret.status) {
                 // 更新 私信通知数量 -1 （该信息已读）
                 this.$store.commit("storeMessage", {official: 0, letter: -1, notify: 0});
               }
            });
          }
        } else {  // 某个好友发过来的消息，但此时 不属于正在聊天的 对象，则 获取该好友，并显示小红点！
          let friendId = message.fromUser;
          // 查询 该好友 ID 对应的 用户  unreadCount
          let flag = false; // 标记是否找到该好友
          for (let i = 0; i < this.friends.length; i++) {
            let friend = this.friends[i];
            if (friend.id === friendId) {
              if (friend.unreadCount < 99) {
                friend.unreadCount++;
              }
              // 移除该好友、并添加到最前面
              if (i != 0) {
                this.friends.splice(i, 1);
                this.friend.unshift(friend);
              }
              flag = true ;
              break;
            }
          }
          // 如果没有找到该好友，说明该好友是 刚刚被别人关注的，将新好友置顶
          if (!flag) {
            // 查询该用户的基本信息并将该好友添加到所有好友的前面
            this.$api.queryUserChatMessage(friendId).then(ret => {
              if (ret.status) {
                this.friends.unshift(ret.data);
              }
            })
          }
        }
      }
    },
    sendMessage() {
      if (this.content != null && this.content.length > 0) {
        let currentUser = this.currentUser;
        // 获取 整个消息对象
        let message = {fromUser: currentUser.id, toUser: this.to, content: this.content, avatar: currentUser.avatar};
        // 发送消息
        if (this.socket.readyState === 1) {
          this.socket.send(JSON.stringify(message));
          this.content = "";
        }
      }
    },
    scrollToBottom() {
      let screen = document.querySelector(".chat div.msg");
      screen.scrollTop = screen.scrollHeight;
    },
    queryFriendList() {
      this.$api.queryFriends().then(ret => {
        if (ret.status) {
          this.friends = ret.list;
        }
      })
    },
    queryChatRecords() {
      this.$api.queryMessageRecords(this.offset, this.friend.unreadCount, this.friend.id).then(ret => {
        if (ret.status) {
          if (ret.list.length > 0) {
            this.messages.unshift(...ret.list.reverse());
            this.finished = false;
          } else {
            this.finished = true;
          }
          this.friend.unreadCount = 0;
        }
      })
    },
    handleChat(friend) {
      this.friend = friend;
      this.content = ""; // 清空发送的聊天信息
      this.messages = []; // 聊天偏移量为0
      this.finished = true; // 重置聊天读完标记
      this.forbidden = false ; // 重置
      // 将未读聊天信息 减少 unreadCount个
      this.$store.commit("storeMessage", {official: 0, letter: -1 * friend.unreadCount , notify: 0});
      this.queryChatRecords();
    },
    handleAddBlack(userId) { // 添加黑名单
       this.$api.bindBlackUser(userId).then(ret=> {
          if (ret.status) {
            this.$toastr.success("当前好友已被加入黑名单、您不会再收到该用户向您发送的消息");
          }
       })
    }
  },
  directives: {
    active: {
      mounted(el, binding) {
         if (el.classList.contains("active")) {
           el.click();
         }
      },
    }
  }
}
</script>

<style scoped>
.message {
  display: block;
  text-align: center;
  font-size: 10px;
  color: #f00;
}
</style>